/**
 * AI诊断服务模块
 * 负责与Doubao多模态大模型API交互
 */
const { OpenAI } = require('openai');
const logger = require('../utils/logger');

// 初始化OpenAI客户端，全局只需初始化一次可提高性能
const openai = new OpenAI({
  apiKey: process.env.ARK_API_KEY,
  baseURL: 'https://ark.cn-beijing.volces.com/api/v3',
  timeout: 60000, // 超时设置为60秒
});

/**
 * 调用Doubao多模态大模型API进行植物诊断
 * @param {string} plantName - 植物名称
 * @param {string} imageBase64 - Base64编码的图片数据
 * @param {string} region - 地区信息
 * @param {string} season - 季节信息
 * @param {object} plantInfo - 识别结果
 * @returns {Promise} 诊断结果
 */
async function callDoubaoApi(plantName, imageBase64, region, season, plantInfo) {
  try {
    // 从环境变量获取API密钥
    const apiKey = process.env.ARK_API_KEY;
    if (!apiKey) {
      logger.error('缺少ARK_API_KEY环境变量配置');
      throw new Error('未配置ARK_API_KEY环境变量');
    }

    logger.info(`准备调用Doubao多模态大模型API，植物: ${plantName}`, {
      apiKeyLength: apiKey ? apiKey.length : 0,
      imageDataLength: imageBase64 ? (typeof imageBase64 === 'string' ? imageBase64.length : '非字符串类型') : 0
    });

    // 检查imageBase64格式，确保它是纯base64，不包含前缀
    let imageUrl = imageBase64;
    if (imageBase64 && !imageBase64.startsWith('data:image')) {
      imageUrl = `data:image/jpeg;base64,${imageBase64}`;
      logger.info('已为诊断图像添加前缀');
    }

    // 构造提示语，定制您需要的输出格式
    const prompt = `请对这个植物图像进行健康状况诊断。植物名称：${plantName || '未知'}
    地区：${region || '未指定'}
    季节：${season || '未指定'}
    请回答以下问题：
    1. 这个植物看起来健康吗？如果不健康，描述病症状况。
    2. 可能的病因是什么？
    3. 推荐的治疗方法和注意事项。
    4. 预防类似问题的建议。
    请以结构化的方式组织回答，使用Markdown格式，分别用"## 诊断结果"、"## 病因分析"、"## 治疗建议"和"## 预防措施"作为标题。可以使用Markdown的基本格式如**加粗**、*斜体*等增强可读性。`;

    const response = await openai.chat.completions.create({
      model: "doubao-1.5-vision-pro-32k-250115",
      messages: [
        {
          role: "user",
          content: [
            { type: "text", text: prompt },
            {
              type: "image_url",
              image_url: { url: imageUrl },
            }
          ]
        }
      ],
      max_tokens: 2000
    });

    logger.debug('Doubao API响应结构', {
      hasChoices: !!response?.choices,
      choicesLength: response?.choices?.length || 0,
      usageInfo: response?.usage || 'No usage info'
    });

    if (response && response.choices && response.choices.length > 0) {
      const content = response.choices[0].message.content;
      logger.info("成功获取Doubao回复", {
        contentPreview: content.substring(0, 50) + '...',
        contentLength: content.length
      });

      // 解析和提取AI返回的内容
      const diagnosisInfo = extractDiagnosisInfo(content, plantName);
      diagnosisInfo.fullContent = content;
      return diagnosisInfo;
    } else {
      logger.error("Doubao API返回数据格式异常", response);
      throw new Error("无法解析AI诊断响应");
    }
  } catch (error) {
    logger.error('调用Doubao API出错', {
      message: error.message,
      stack: error.stack,
      response: error.response ? {
        status: error.response.status,
        data: error.response.data
      } : null
    });
    throw error;
  }
}

/**
 * 使用豆包模型识别植物类型
 * @param {string} imageBase64 - Base64编码的图片数据
 * @returns {Promise} 识别结果，包含植物名称等信息
 */
async function identifyPlantWithDoubao(imageBase64) {
  try {
    // 从环境变量获取API密钥
    const apiKey = process.env.ARK_API_KEY;
    if (!apiKey) {
      logger.error('缺少ARK_API_KEY环境变量配置');
      throw new Error('未配置ARK_API_KEY环境变量');
    }

    logger.info(`准备使用豆包模型识别植物种类`);

    // 添加类型检查，确保imageBase64是字符串
    if (!imageBase64 || typeof imageBase64 !== 'string') {
      logger.error('图像数据无效：不是字符串类型或为空');
      throw new Error('图像数据格式无效，必须是Base64编码的字符串');
    }

    let imageUrl = imageBase64;
    if (!imageBase64.startsWith('data:image')) {
      // 添加前缀
      imageUrl = `data:image/jpeg;base64,${imageBase64}`;
      logger.info('已为图像数据添加前缀');
    }

    // 使用SDK调用API
    const response = await openai.chat.completions.create({
      model: "doubao-1.5-vision-pro-32k-250115",
      messages: [
        {
          role: "user",
          content: [
            {
              type: "text",
              text: "这是一张植物的照片，请帮我识别是什么植物？请提供以下信息：\n1. 植物的中文名\n2. 拉丁学名\n3. 科属的分类\n4. 基本特征描述\n请以结构化方式回答，先给出明确的植物名称。可以使用Markdown格式增强可读性。"
            },
            {
              type: "image_url",
              image_url: {
                url: imageUrl
              }
            }
          ]
        }
      ],
      max_tokens: 4096 // 适当限制token数量可加速响应
    });

    if (response && response.choices && response.choices.length > 0) {
      const content = response.choices[0].message.content;
      logger.info("成功获取植物识别结果", {
        contentLength: content.length,
        preview: content.substring(0, 50) + '...'
      });

      // 解析植物信息
      const plantInfo = extractPlantIdentificationInfo(content);
      return plantInfo;
    } else {
      logger.error("植物识别API返回数据格式异常", response);
      throw new Error("无法解析植物识别响应");
    }
  } catch (error) {
    logger.error('植物识别API调用失败', {
      message: error.message,
      stack: error.stack
    });
    throw error;
  }
}

/**
 * 从AI响应中提取结构化诊断信息
 * @param {string} content - AI回复内容
 * @param {string} plantName - 植物名称
 * @returns {object} 结构化的诊断信息
 */
function extractDiagnosisInfo(content, plantName) {
  // 基本结构
  const diagnosisInfo = {
    diagnosis: "",
    treatment: "",
    preventionTips: "",
    growthAdvice: "",
    fullContent: content // 保存完整内容
  };

  // 分段处理，更有效地提取关键信息
  const paragraphs = content.split(/\n\s*\n/); // 按空行分段

  // 提取诊断信息 - 通常在开头两段
  if (paragraphs.length > 0) {
    // 以第一段作为诊断内容
    diagnosisInfo.diagnosis = paragraphs[0].substring(0, 150) + (paragraphs[0].length > 150 ? '...' : '');
    
    // 查找治疗或解决方案相关内容
    const treatmentKeywords = ['治疗', '防治', '解决', '控制', '改善', '处理'];
    let treatmentFound = false;
    
    for (let i = 0; i < paragraphs.length; i++) {
      // 查找含有关键词的段落
      for (const keyword of treatmentKeywords) {
        if (paragraphs[i].includes(keyword)) {
          diagnosisInfo.treatment = paragraphs[i];
          treatmentFound = true;
          break;
        }
      }
      if (treatmentFound) break;
    }
    
    // 如果未找到治疗方案，则使用第二段作为治疗方案（如果存在）
    if (!treatmentFound && paragraphs.length > 1) {
      diagnosisInfo.treatment = paragraphs[1];
    }
    
    // 查找预防建议
    let preventionIndex = -1;
    for (let i = 0; i < paragraphs.length; i++) {
      if (paragraphs[i].includes('预防') || paragraphs[i].includes('防范')) {
        diagnosisInfo.preventionTips = paragraphs[i];
        preventionIndex = i;
        break;
      }
    }

    // 查找种植建议
    let adviceIndex = -1;
    for (let i = 0; i < paragraphs.length; i++) {
      if ((paragraphs[i].includes('建议') || paragraphs[i].includes('种植') || 
           paragraphs[i].includes('栽培') || paragraphs[i].includes('养护')) && i !== preventionIndex) {
        diagnosisInfo.growthAdvice = paragraphs[i];
        adviceIndex = i;
        break;
      }
    }

    // 如果没有找到预防建议，使用默认文本
    if (!diagnosisInfo.preventionTips) {
      diagnosisInfo.preventionTips = `对于${plantName}，建议定期检查植物健康状况，保持适宜的生长环境。`;
    }
    
    // 如果没有找到种植建议，使用默认文本
    if (!diagnosisInfo.growthAdvice) {
      diagnosisInfo.growthAdvice = `种植${plantName}时，建议根据当地气候条件和土壤特性进行适应性栽培。`;
    }
  }
  return diagnosisInfo;
}

/**
 * 从豆包API响应中提取植物识别信息
 * @param {string} content - API返回的内容
 * @returns {object} 提取的植物信息
 */
function extractPlantIdentificationInfo(content) {
  // 基本结构
  const plantInfo = {
    cname: "",     // 中文名
    latin: "",     // 拉丁学名
    family: "",    // 科属
    features: "",  // 特征描述
    isPlant: true, // 是否为植物
    fullContent: content // 保存完整内容
  };

  // 检查是否识别为非植物
  if (content.includes("不是植物") || content.includes("这张图片不是") || content.includes("无法识别为植物")) {
    plantInfo.isPlant = false;
    plantInfo.cname = "非植物";
    return plantInfo;
  }
  
  // 尝试提取植物名称
  const nameMatches = content.match(/[\u4e00-\u9fa5]{2,}(?=是|，|。|\(|\（|\n|，)/);
  if (nameMatches && nameMatches[0]) {
    plantInfo.cname = nameMatches[0].trim();
  }

  // 尝试提取拉丁学名
  const latinMatches = content.match(/[A-Z][a-z]+\s+[a-z]+/);
  if (latinMatches && latinMatches[0]) {
    plantInfo.latin = latinMatches[0].trim();
  }

  // 尝试提取科属 - 改进的正则表达式
  const familyMatches = content.match(/(?:属于|科[：:：]?|科属[：:：]?|分类[：:：]?)\s*([\u4e00-\u9fa5]+科[\u4e00-\u9fa5]*属?)/);
  if (familyMatches && familyMatches[1]) {
    plantInfo.family = familyMatches[1].trim();
  }

  // 尝试提取特征描述
  const featuresMatches = content.match(/(?:基本特征|特征描述|主要特征|形态特征)[:：]([\s\S]+?)(?=\n\n|\n\d|$)/);
  if (featuresMatches && featuresMatches[1]) {
    plantInfo.features = featuresMatches[1].trim();
  }

  // 如果没有提取到名称，使用默认值
  if (!plantInfo.cname) {
    plantInfo.cname = "未知植物";
  }
  return plantInfo;
}

/**
 * 生成默认的诊断响应（当API调用失败时使用）
 * @param {string} plantName - 植物名称
 * @returns {object} 默认诊断信息
 */
function generateDefaultDiagnosis(plantName) {
  return {
    diagnosis: `无法获取${plantName}的AI诊断，请检查网络连接或API配置。`,
    treatment: "建议: 1.观察植物生长情况; 2.保持适当浇水; 3.保持通风，避免过度浇水。",
    preventionTips: "预防建议: 1.选择健康种苗; 2.合理密植; 3.避免高湿环境; 4.定期检查植物健康状况。",
    growthAdvice: "种植建议: 1.保持适宜土壤湿度; 2.适量施肥; 3.定期松土除草; 4.适时浇水，避免旱涝。"
  };
}

/**
 * 整合植物诊断调用服务
 * @param {string} plantName 植物名称
 * @param {string} imageBase64 图片base64编码
 * @param {string} region 地区
 * @param {string} season 季节
 * @param {object} plantInfo 植物识别信息
 * @returns {Promise<object>} 诊断结果
 */
async function diagnose(plantName, imageBase64, region, season, plantInfo) {
  logger.info(`开始诊断植物: ${plantName}`);
  
  try {
    const result = await callDoubaoApi(plantName, imageBase64, region, season, plantInfo);
    return result;
  } catch (error) {
    logger.error(`植物诊断失败: ${plantName}`, {
      errorMessage: error.message
    });
    return {
      ...generateDefaultDiagnosis(plantName),
      error: error.message
    };
  }
}

module.exports = {
  diagnose,
  identifyPlantWithDoubao // 导出植物识别函数
};